package com.asset.dispoal.business.bsAgreement.service.commom;

import com.asset.dispoal.business.bsAgreement.domain.db.mapper.AgreementMapper;
import com.asset.dispoal.business.bsAgreement.dto.AgreementResponse;
import com.asset.dispoal.business.bsAgreement.dto.EvidenceDataRequest;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.entity.MatchSuccessEvidence;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.entity.RemoveEvidenceContract;
import com.asset.dispoal.business.bsEvidenceRecognition.domain.db.mapper.BusinessDataManageMapper;
import com.asset.dispoal.business.bsEvidenceRecognition.dto.ContractEvidenceResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.mhuang.pacebox.core.ddd.BaseCommand;
import tech.mhuang.pacebox.core.page.PageUtil;
import tech.mhuang.pacebox.core.timer.SystemClock;
import tech.mhuang.pacebox.core.util.CollectionUtil;
import tech.mhuang.pacebox.core.util.StringUtil;
import tech.mhuang.pacebox.springboot.core.local.GlobalHeaderThreadLocal;
import tech.mhuang.pacebox.springboot.protocol.Result;
import tech.mhuang.pacebox.springboot.protocol.data.PageVO;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Component
@Slf4j
public class QueryEvidenceDataPageCommand implements BaseCommand<EvidenceDataRequest, Result<PageVO<AgreementResponse>>> {

    @Autowired
    private BusinessDataManageMapper businessDataManageMapper;

    @Autowired
    private AgreementMapper agreementMapper;

    @Override
    public Result<PageVO<AgreementResponse>> execute(EvidenceDataRequest request) {
        // 查询搜索的对应数据
        long beginTime = SystemClock.now();
        List<Map<String, String>> mapList = businessDataManageMapper.queryDataDetail(request.getAssetInstBatchId());
        List<Map<String, Object>> agreementDataList = businessDataManageMapper.queryResultByEvidenceDataRequest(request, mapList);
        //匹配成功的证据
        List<MatchSuccessEvidence> matchSuccessEvidenceList = businessDataManageMapper.queryMatchSuccessEvidence(request.getAssetInstBatchId(), request.getEvidenceTypeId(), null);
        //删除的证据
        List<RemoveEvidenceContract> removeEvidenceContractList = businessDataManageMapper.queryRemoveEvidenceContract(request.getAssetInstBatchId(), request.getEvidenceTypeId(), null);
        //数据需要匹配上的种类
        List<ContractEvidenceResponse> evidenceResponseList = businessDataManageMapper.queryEvidenceTypeByAssetInstBatchId(request.getAssetInstBatchId(), request.getEvidenceTypeId(), null);
        //根据证据种类进行分组
        Map<String, List<MatchSuccessEvidence>> evidenceTypeSuccessMap = matchSuccessEvidenceList.stream().collect(Collectors.groupingBy(MatchSuccessEvidence::getEvidenceTypeId));
        Map<String, List<RemoveEvidenceContract>> removeEvidenceContractMap = removeEvidenceContractList.stream().collect(Collectors.groupingBy(RemoveEvidenceContract::getEvidenceTypeId));
        log.info("sql结束时间:{}", (SystemClock.now() - beginTime));
        List<String> successIdSet = new CopyOnWriteArrayList<>();
        beginTime = SystemClock.now();
        agreementDataList.parallelStream().forEach(agreementData -> {
            AtomicBoolean checkAgreementEvidence = new AtomicBoolean(Boolean.TRUE);
            for (ContractEvidenceResponse evidence : evidenceResponseList) {
                //当前种类下的证据
                List<MatchSuccessEvidence> evidenceTypeList = evidenceTypeSuccessMap.get(evidence.getId());
                //删除种类下的证据
                List<RemoveEvidenceContract> removeEvidenceTypeList = removeEvidenceContractMap.get(evidence.getId());
                List<MatchSuccessEvidence> matchSuccessEvidences = evidenceTypeList;
                if (CollectionUtil.isNotEmpty(removeEvidenceTypeList)) {
                    Set<String> removeEvidenceIdSet = removeEvidenceTypeList.stream()
                            .filter(removeEvidenceType -> agreementData.get("contractId").equals(removeEvidenceType.getContractId()))
                            .map(RemoveEvidenceContract::getEvidenceId)
                            .collect(Collectors.toSet());
                    matchSuccessEvidences = matchSuccessEvidences.stream().filter(evidenceType -> !removeEvidenceIdSet.contains(evidenceType.getEvidenceId())).collect(Collectors.toList());
                }
                if (CollectionUtil.isEmpty(matchSuccessEvidences)) {
                    checkAgreementEvidence.compareAndSet(Boolean.TRUE, Boolean.FALSE);
                    break;
                }
                AtomicBoolean checkEvidenceType = new AtomicBoolean(Boolean.FALSE);

                for (MatchSuccessEvidence matchSuccessEvidence : matchSuccessEvidences) {
                    //无需匹配的证据直接返回当前成功
                    if (StringUtil.isEmpty(matchSuccessEvidence.getAlias())) {
                        checkEvidenceType.compareAndSet(Boolean.FALSE, Boolean.TRUE);
                        break;
                    }
                    try {
                        if (agreementData.get(matchSuccessEvidence.getAlias()) != null) {
                            //证据匹配上的返回成功
                            if (agreementData.get(matchSuccessEvidence.getAlias()).equals(matchSuccessEvidence.getResult())) {
                                checkEvidenceType.compareAndSet(Boolean.FALSE, Boolean.TRUE);
                                break;
                            }
                        }
                    } catch (Exception ignore) {
                    }

                }
                if (!checkEvidenceType.get()) {
                    checkAgreementEvidence.compareAndSet(Boolean.TRUE, Boolean.FALSE);
                    break;
                }
            }
            if (!checkAgreementEvidence.get()) {
                successIdSet.add((String) agreementData.get("contractId"));
            }
        });

        log.info("程序处理结束时间:{}", (SystemClock.now() - beginTime));
        PageVO<AgreementResponse> pageVo = new PageVO<>();
        pageVo.setTotalSize(successIdSet.size());
        List<String> idList = PageUtil.subList(successIdSet, request.getStart() - 1, request.getRows());

        String permission = (String) GlobalHeaderThreadLocal.get().getExtraMap().get("permission");
        if (CollectionUtil.isNotEmpty(idList)) {
            pageVo.setResult(agreementMapper.queryAgreementDataList(idList, permission));
        }
        // 循环证据种类
        return Result.ok(pageVo);
    }
}
